{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setting Things Up\n",
    "\n",
    "To use TorchSharp, you need some packages from NuGet.\n",
    "\n",
    "First and foremost, you need to download the most recent version of the `TorchSharp` package at [https://www.nuget.org/packages/TorchSharp/](https://www.nuget.org/packages/TorchSharp/). That's the .NET bindings to libtorch, and it contains the .NET API. However, you also need one of several packages containing distributions of libtorch itself, the highly capable native-code engine behind PyTorch.\n",
    "\n",
    "Starting with version 0.93.4, there are bundled versions of these packages, which is what these tutorials rely on.\n",
    "\n",
    "The basic backend supports training and inference on CPUs, but there is also support for CUDA on Windows and Linux, for use on machines with compatible hardware. Using CUDA for training can speed things up by orders of magnitude, so it's important to use the right backend.\n",
    "\n",
    "These are the various libtorch packages:\n",
    "\n",
    "|Name|URL|Description|\n",
    "|-----|-----------------|--------------|\n",
    "|TorchSharp-cpu|https://www.nuget.org/packages/TorchSharp-cpu/|TorchSharp with only the CPU backend, which works on Windows, Linus, and MacOS|\n",
    "|TorchSharp-cuda-windows|https://www.nuget.org/packages/TorchSharp-cuda-windows/|A CUDA backend with only Windows binaries|\n",
    "|TorchSharp-cuda-linux|https://www.nuget.org/packages/TorchSharp-cuda-linux/|A CUDA backend with only Linux binaries|"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All the tutorial notebooks (with the exception of the one that covers CUDA) will rely on the CPU package, since that takes up the least amount of disk space and works everywhere. If you have access to a CUDA processor, replace the package name with the applicable Windows or Linux package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "#r \"nuget:TorchSharp-cpu\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Opening\n",
    "\n",
    "Once you have the right NuGet packages, the next thing is to get the right open directives at the top of your source files. TorchSharp consists of a lot of namespaces and static classes, and to make programming TorchSharp convenient, you usually need to include a several of them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "open TorchSharp\n",
    "\n",
    "open type TorchSharp.torch\n",
    "open type TorchSharp.torch.nn\n",
    "open type TorchSharp.torch.nn.functional\n",
    "open type TorchSharp.TensorExtensionMethods"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, for these tutorials, it would obscure the API to have too many `open` directives. It's better, for pedagocial reasons, to explicitly qualify names until their scope becomes well known. So, the tutorials will generally use a minimal set of `open` directives."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Formatting\n",
    "\n",
    ".NET Interactive will, by default, display the fields and properties of the objects that are found at the end of each cell. \n",
    "\n",
    "Before v0.100.3, you had to add the following code to the top of each notebook:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "open Microsoft.DotNet.Interactive.Formatting\n",
    "\n",
    "Formatter.SetPreferredMimeTypesFor(typeof<torch.Tensor>, \"text/plain\")\n",
    "Formatter.Register<torch.Tensor>(fun (x:torch.Tensor) -> x.ToString(TorchSharp.TensorStringStyle.Default))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But that is no longer necessary. You can still do so if you want to keep code as it is, but TorchSharp is now better integrated with .NET Interactive and will do it automatically."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that there are now three styles that may be used to format tensor output: C#-style, NumPy-style and Julia-style. The default is 'Julia,' but if you continue to use he top-of-notebook formatting, whatever you set it to in the cell at the top will be used to format tensors automatically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "torch.ones(2,3,3)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " The 'Default' style means that the actual format is picked up at runtime from the global style, which is 'Julia' unless you set it to 'NumPy' or 'CSharp' (sorry, no F# styling yet.):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "torch.TensorStringStyle <- torch.numpy;\n",
    "\n",
    "torch.ones(2,3,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "fsharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "torch.TensorStringStyle <- torch.csharp;\n",
    "\n",
    "torch.rand(2,3,3)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For a more in-depth description of tensor formatting, see: [TorchSharp Wiki - Tensor String Frmatting](https://github.com/dotnet/TorchSharp/wiki/Tensor-String-Formatting)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "file_extension": ".cs",
   "mimetype": "text/x-csharp",
   "name": "C#",
   "pygments_lexer": "csharp",
   "version": "9.0"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
